home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Testing & Debugging / Debuggers & dcmds / MacsBug 6.5.2 / dcmds / C Samples / File.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-26  |  7.3 KB  |  319 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        File.c
  3.  
  4.     Contains:    This is the FCB dcmd.
  5.  
  6.     Written by:    JM3 = Jim Murphy
  7.                 DAL = Dave Lyons
  8.                 sad = Scott Douglas
  9.  
  10.     Copyright:    © 1988,1993-1995 by Apple Computer, Inc., all rights reserved.
  11.  
  12.     Change History (most recent first):
  13.  
  14.          <7>     4/18/95    DAL        Omit some boring fields from the "file 0" display (for logs).
  15.          <6>     2/21/95    DAL        Made "file 0" show all open files except for fonts (to help
  16.                                     shrink Standard Logs). Bumped version to 3.0.1.
  17.          <5>   10-Dec-94    JM3        Updated for new format 3 dcmd requirements.
  18.          <4>     5/13/94    DAL        Deal with carriage returns inside filenames (changed put.c).
  19.          <3>   24-Jan-94    JM3        With the Universal Interfaces, EqualString is now in
  20.                                     TextUtils.h. Blah.
  21.          <2>     9/13/93    DAL        made some columns wider and fixed the filename-prefix feature to
  22.                                     work again
  23.  
  24.     Modification history:
  25.         29Nov88 sad        revised for new dcmd names.
  26.          5Oct88    sad        broke out formatting routines to put.c
  27.         30Sep88 sad        written
  28.  
  29.     The following MPW commands will build the dcmd and copy it to the
  30.     "Debugger Prefs" file in the System folder. The dcmd's name in
  31.     MacsBug will be the name of the file built by the Linker.
  32.     You must first copy dcmd.h, dcmdGlue.a.o and DRunTime.o from the
  33.     C Samples folder into this folder.
  34.  
  35.     C Put.c
  36.     C File.c
  37.     Link dcmdGlue.a.o File.c.o put.c.o DRuntime.o "{Libraries}"Interface.o -o File
  38.     BuildDcmd File 1003
  39.     Echo 'include "File";'    |    Rez -a -o "{systemFolder}Debugger Prefs"
  40. */
  41.  
  42. #include <Types.h>
  43. #include <Memory.h>
  44. #include <Files.h>
  45. #include <OSUtils.h>
  46. #include <TextUtils.h>
  47.  
  48. #include "dcmd.h"
  49. #include "put.h"
  50.  
  51. #define FSFCBLen 0x3f6
  52. #define FCBsPtr  0x34e
  53.  
  54.  
  55. typedef struct FCB
  56. {
  57.     unsigned long fcbFlNum;
  58.     unsigned char fcbMdRByt;
  59.     unsigned char fcbTypByt;
  60.     unsigned short fcbSBlk;
  61.     unsigned long fcbEOF;
  62.     unsigned long fcbPLen;
  63.     unsigned long fcbCrPs;
  64.     VCB* fcbVPtr;
  65.     void* fcbBfAdr;
  66.     unsigned short fcbFlPos;
  67.     unsigned long fcbClmpSize;
  68.     void* fcbBTCBPtr;
  69.     unsigned long fcbExtRec[3];
  70.     OSType fcbFType;
  71.     unsigned long fcbCatPos;
  72.     unsigned long fcbDirID;
  73.     char fcbCName[32];
  74. }
  75.     FCB;
  76.  
  77.  
  78. static void DrawHdr(Boolean shortForm)
  79. {
  80. //                                 1         2         3         4         5         6         7
  81. //                        1234567890123456789012345678901234567890123456789012345678901234567890
  82.  
  83.     if (shortForm)
  84.         dcmdDrawLine("\pfRef File                   Vol         Type Fl Fork     LEof");
  85.     else
  86.         dcmdDrawLine("\pfRef File                   Vol         Type Fl Fork     LEof     Mark  FlNum Parent FCB at");
  87. }
  88.  
  89.  
  90. static Boolean IsFontFile(FCB *fcbp)
  91. {
  92.     OSType filetype = fcbp->fcbFType;
  93.  
  94.     if (filetype == 'FFIL' || filetype == 'ffil' || filetype == 'tfil')
  95.         return true;
  96.  
  97.     return false;
  98. }
  99.  
  100.  
  101. static void DrawFCB(int fref, FCB* fcbp, Boolean shortForm)
  102. {
  103.     PutUHexWord(fref);
  104.     PutSpace();
  105.     PutPStrTruncTo(fcbp->fcbCName, 17+10);
  106.     PutSpace();
  107.     PutPStrTruncTo(fcbp->fcbVPtr->vcbVN, 26+10+3);
  108.     PutSpace();
  109.     PutOSType(fcbp->fcbFType);
  110.     PutSpace();
  111.     PutChar((fcbp->fcbMdRByt & 0x80) ? 'D' : 'd');
  112.     PutChar((fcbp->fcbMdRByt & 0x01) ? 'W' : 'w');
  113.     PutSpace();
  114.     if (fcbp->fcbMdRByt & 0x02)
  115.         PutPStr("\prsrc ");
  116.     else
  117.         PutPStr("\pdata ");
  118.     PutUDecTo(fcbp->fcbEOF,47+11+3);
  119.  
  120.     if (!shortForm)
  121.     {
  122.         PutSpace();
  123.         PutUDecTo(fcbp->fcbCrPs,55+12+3);
  124.         PutSpace();
  125.         PutUHexZTo(fcbp->fcbFlNum,6,62+12+3);
  126.         PutSpace();
  127.         PutUHexZTo(fcbp->fcbDirID,6,69+12+3);
  128.         PutSpace();
  129.         PutUHexZTo((unsigned long)fcbp,6,76+12+3);
  130.     }
  131.  
  132.     PutLine();
  133. }
  134.  
  135.  
  136. // PrefixPStr
  137. //         returns true if astr is equal to a prefix of bstr.
  138. //        (astr must not be longer than 31 characters)
  139.  
  140. static Boolean PrefixPStr(const Str255 astr, const Str255 bstr)
  141. {
  142.     char newstr[31];
  143.     int alen = *astr;
  144.     int blen = *bstr;
  145.  
  146.     if (alen <= blen)
  147.     {
  148.         BlockMoveData(bstr+1, newstr+1, alen);
  149.         newstr[0] = alen;
  150.         return EqualString(astr, newstr, false, true);
  151.     }
  152.     else
  153.         return false;    
  154. }
  155.  
  156.  
  157.  
  158. pascal void CommandEntry(dcmdBlock* paramPtr)
  159. {
  160.     static const char usageStr[] = "\p[fRefNum|\"file name\"]";
  161.  
  162.     switch (paramPtr->request)
  163.     {
  164.         case dcmdInit:
  165.             break;
  166.  
  167.         case dcmdHelp:
  168.             dcmdDrawLine("\pDisplays file information on all open files, or for the given fRefNum");
  169.             dcmdDrawLine("\por filename. Flags are D/d=Dirty, W/w=writeable.  \"file 0\" shows all");
  170.             dcmdDrawLine("\popen files except for fonts.");
  171.             break;
  172.  
  173.         case dcmdGetInfo:
  174.             * (long *) &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->dcmdVersion = 0x03018000; // version 3.0.1 final
  175.             BlockMoveData(&usageStr, &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->usageStr, usageStr[0]+1);
  176.             break;
  177.  
  178.         case dcmdDoIt:
  179.         {
  180.             Boolean    doOneFCB = false;
  181.             long    fref;
  182.             short    c;
  183.             Boolean    haveFileName = false;
  184.             Str255    filename;
  185.             int        fcbLen;                // the length of one fcb
  186.             char*    fcbsbase;
  187.             int        fcbslen;            // the length of the fcbs block
  188.  
  189.             dcmdSwapWorlds();
  190.  
  191.             dcmdDrawLine("\pDisplaying File Control Blocks");
  192.  
  193.             // get low-memory values after dcmdSwapWorlds()
  194.             fcbLen   = * (unsigned short *) FSFCBLen;
  195.             fcbsbase = * (char **) FCBsPtr;
  196.             fcbslen  = * (unsigned short *) fcbsbase;
  197.  
  198.             if (fcbLen != sizeof(FCB))
  199.             {
  200.                 PutPStr("\FSFCBLen = ");
  201.                 PutUDec(fcbLen);
  202.                 PutPStr("\p expected ");
  203.                 PutUDec(fcbLen);
  204.                 PutLine(sizeof(FCB));
  205.             }
  206.             if ((fcbslen - 2) % fcbLen != 0)
  207.             {
  208.                 PutPStr("\pBad fcbslen ");
  209.                 PutUHexWord(fcbslen);
  210.                 PutLine();
  211.             }
  212.  
  213.             c = dcmdPeekAtNextChar();
  214.             if (c == '"' || c == '\'')
  215.             {
  216.                 haveFileName = true;
  217.                 (void) dcmdGetNextParameter(filename);
  218.             }
  219.             else
  220.                 (void) dcmdGetNextExpression(&fref, &doOneFCB);
  221.  
  222.             if (doOneFCB && fref)
  223.             {
  224.                 fref = (unsigned short) fref;
  225.                 if ((fref > fcbslen) || ((fref - 2) % fcbLen != 0))
  226.                 {
  227.                     PutPStr("\pBad file refnum ");
  228.                     PutUHexWord(fref);
  229.                     PutLine();
  230.                 }
  231.                 else
  232.                 {
  233.                     FCB* fcbp = (FCB*)(fref + fcbsbase);
  234.                     if (fcbp->fcbFlNum)
  235.                     {
  236.                         DrawHdr(false /* long form */);
  237.                         DrawFCB(fref, fcbp, false /* long form */);
  238.                     }
  239.                     else
  240.                     {
  241.                         PutPStr("\pFCB ");
  242.                         PutUHexWord(fref);
  243.                         PutPStr("\p is not in use");
  244.                         PutLine();
  245.                     }
  246.                 }
  247.             }
  248.             else        // there was no refnum on the command line (or it was 0)
  249.             {
  250.                 int numFCBs = (fcbslen - 2) / fcbLen;
  251.                 int fcbsUsed = 0;
  252.                 int numFontsSkipped = 0;
  253.                 Boolean foundOne = false;
  254.  
  255.                 for (fref = 2; (fref < fcbslen) && (!paramPtr->aborted); fref += fcbLen)
  256.                 {
  257.                     FCB* fcbp = (FCB *) (fcbsbase + fref);
  258.  
  259.                     if (fcbp->fcbFlNum && (!haveFileName || PrefixPStr(filename,fcbp->fcbCName)))
  260.                     {
  261.                         fcbsUsed++;
  262.                         if (!foundOne)
  263.                         {
  264.                             DrawHdr(doOneFCB);        // true = short form ("file 0")
  265.                             foundOne = true;
  266.                         }
  267.  
  268.                         if (doOneFCB && IsFontFile(fcbp))
  269.                             numFontsSkipped++;
  270.                         else
  271.                             DrawFCB(fref, fcbp, doOneFCB /* true for short form */);
  272.                     }
  273.                 }
  274.  
  275.                 if (!paramPtr->aborted)
  276.                 {
  277.                     if (haveFileName)
  278.                     {
  279.                         if (!foundOne)
  280.                         {
  281.                             PutPStr("\pNo open files match \"");
  282.                             PutPStr(filename);
  283.                             PutChar('"');
  284.                             PutLine();
  285.                         }
  286.                     }
  287.                     else
  288.                     {
  289.                         PutUDec(numFCBs);
  290.                         PutPStr("\p FCBs, ");
  291.                         PutUDec(fcbsUsed);
  292.                         PutPStr("\p in use");
  293.  
  294.                         if (numFontsSkipped)
  295.                         {
  296.                             PutPStr("\p (including ");
  297.                             PutUDec(numFontsSkipped);
  298.                             PutPStr("\p fonts not listed)");
  299.                         }
  300.                         PutPStr("\p, ");
  301.  
  302.                         PutUDec(numFCBs - fcbsUsed);
  303.                         PutPStr("\p free");
  304.                         PutLine();
  305.                     }
  306.                 }
  307.             }    
  308.  
  309.             dcmdSwapWorlds();
  310.             break;
  311.         }
  312.  
  313.         // Format 3 and newer dcmds must quietly ignore requests we don't recognize.
  314.  
  315.         default:
  316.             break;
  317.     }
  318. }
  319.